package bean;

import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Area;

import javax.swing.JFrame;

import com.patni.frame.util.Common;
import com.sun.awt.AWTUtilities;

public class SelectableCanvas extends JFrame {

	private static final long serialVersionUID = -7159915510292362753L;

	boolean selecting;// 是否正在拖拽矩形
	int x, y;// 矩形原点坐标

	PointRectangle selection;// 当前绘制的矩形
	int activeHandle = -1;// 激活的Resize手柄
	Rectangle[] handles = new Rectangle[8];// 8个Resize手柄

	public SelectableCanvas() {
		this.setUndecorated(true);
//		this.setAlwaysOnTop(true);
//		AWTUtilities.setWindowOpacity(this, 0.01f);
		this.setBounds(0, 0, 800, 800);
		
		addMouseListener(new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				if (selecting || activeHandle >= 0) {
					wipeSelection();
					confirmSelection(selection);
					selecting = false;
					activeHandle = -1;
					setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
				}
			}

			@Override
			public void mousePressed(MouseEvent e) {
				x = e.getX();
				y = e.getY();
			}
		});

		addMouseMotionListener(new MouseMotionAdapter() {
			public void mouseMoved(MouseEvent e) {
				for (int i = 0; i < handles.length; i++) {
					if (handles[i] != null
							&& handles[i].contains(e.getX(), e.getY())) {
						activeHandle = i;
						switch (i) {
						case 0:
						case 4:
							setCursor(Cursor
									.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
							break;
						case 1:
						case 5:
							setCursor(Cursor
									.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
							break;
						case 2:
						case 6:
							setCursor(Cursor
									.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
							break;
						case 3:
						case 7:
							setCursor(Cursor
									.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
							break;
						}
						return;
					}
				}
				activeHandle = -1;
				setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			}

			public void mouseDragged(MouseEvent e) {
				if (selection != null)
					wipeSelection();
				if (activeHandle >= 0) {
					switch (activeHandle) {
					case 0:
						selection = new PointRectangle(e.getX(), e.getY(),
								selection.x2, selection.y2);
						break;
					case 1:
						selection = new PointRectangle(selection.x1, e.getY(),
								selection.x2, selection.y2);
						break;
					case 2:
						selection = new PointRectangle(selection.x1, e.getY(),
								e.getX(), selection.y2);
						break;
					case 3:
						selection = new PointRectangle(selection.x1,
								selection.y1, e.getX(), selection.y2);
						break;
					case 4:
						selection = new PointRectangle(selection.x1,
								selection.y1, e.getX(), e.getY());
						break;
					case 5:
						selection = new PointRectangle(selection.x1,
								selection.y1, selection.x2, e.getY());
						break;
					case 6:
						selection = new PointRectangle(e.getX(), selection.y1,
								selection.x2, e.getY());
						break;
					case 7:
						selection = new PointRectangle(e.getX(), selection.y1,
								selection.x2, selection.y2);
						break;
					}
					drawSelection(selection);
				} else {
					selection = new PointRectangle(x, y, e.getX(), e.getY());
					drawSelection(selection);
					selecting = true;
					setCursor(Cursor
							.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
				}
			}
		});
		
		
		this.show();
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}

	// 清除选择的矩形
	public void clearSelection() {
		selection = null;
		selecting = false;
		activeHandle = -1;
		for (int i = 0; i < handles.length; i++)
			handles[i] = null;
	}

	// 清除上次的绘制的矩形
	private void wipeSelection() {
		Graphics2D graphics = (Graphics2D) getGraphics().create();// 初始化绘图上下文
		// 定义擦除区域
		Area area = new Area(new Rectangle(selection.x, selection.y,
				selection.width + 1, selection.height + 1));
		area.subtract(new Area(new Rectangle(selection.x + 1, selection.y + 1,
				selection.width - 1, selection.height - 1)));
		area
				.add(new Area(new Rectangle(selection.x - 2, selection.y - 2,
						5, 5)));
		area.add(new Area(new Rectangle(selection.x + selection.width / 2 - 2,
				selection.y - 2, 5, 5)));
		area.add(new Area(new Rectangle(selection.x + selection.width - 2,
				selection.y - 2, 5, 5)));
		area.add(new Area(new Rectangle(selection.x + selection.width - 2,
				selection.y + selection.height / 2 - 2, 5, 5)));
		area.add(new Area(new Rectangle(selection.x + selection.width - 2,
				selection.y + selection.height - 2, 5, 5)));
		area.add(new Area(new Rectangle(selection.x + selection.width / 2 - 2,
				selection.y + selection.height - 2, 5, 5)));
		area.add(new Area(new Rectangle(selection.x - 2, selection.y
				+ selection.height - 2, 5, 5)));
		area.add(new Area(new Rectangle(selection.x - 2, selection.y
				+ selection.height / 2 - 2, 5, 5)));
		graphics.setClip(area);// 应用擦除区域
		update(graphics);// 用背景擦除
	}

	// 画虚线矩形
	private void drawSelection(Rectangle selection) {
		Graphics2D graphics = (Graphics2D) getGraphics().create();// 初始化绘图上下文
		graphics.setPaint(Color.black);// 设置边框颜色
		graphics.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
				BasicStroke.JOIN_ROUND, 1f, new float[] { 5 }, 0));// 设置边框笔触
		graphics.draw(selection);// 绘制选择边框
	}

	// 画带手柄的矩形
	private void confirmSelection(Rectangle selection) {
		this.selection = new PointRectangle(selection);
		Graphics2D graphics = (Graphics2D) getGraphics();// 绘图上下文
		if (selection.isEmpty()) {
			clearSelection();
			return;
		}
		graphics.setStroke(new BasicStroke(1));// 设置选择框底色笔触
		graphics.setPaint(Color.BLUE);// 设置边框底色颜色
		graphics.draw(selection);// 绘制选择边框底色
		graphics.setPaint(Color.WHITE);// 设置边框颜色
		graphics.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
				BasicStroke.JOIN_ROUND, 1f, new float[] { 5 }, 0));// 设置边框笔触
		graphics.draw(selection);// 绘制选择边框
		// 定义手柄
		handles[0] = new Rectangle(selection.x - 2, selection.y - 2, 4, 4);
		handles[1] = new Rectangle(selection.x + selection.width / 2 - 2,
				selection.y - 2, 4, 4);
		handles[2] = new Rectangle(selection.x + selection.width - 2,
				selection.y - 2, 4, 4);
		handles[3] = new Rectangle(selection.x + selection.width - 2,
				selection.y + selection.height / 2 - 2, 4, 4);
		handles[4] = new Rectangle(selection.x + selection.width - 2,
				selection.y + selection.height - 2, 4, 4);
		handles[5] = new Rectangle(selection.x + selection.width / 2 - 2,
				selection.y + selection.height - 2, 4, 4);
		handles[6] = new Rectangle(selection.x - 2, selection.y
				+ selection.height - 2, 4, 4);
		handles[7] = new Rectangle(selection.x - 2, selection.y
				+ selection.height / 2 - 2, 4, 4);
		graphics.setComposite(AlphaComposite.getInstance(
				AlphaComposite.SRC_OVER, 1f));// 设置填充不透明
		graphics.setPaint(Color.WHITE);// 设置手柄填充颜色
		// 填充手柄
		for (Rectangle handle : handles)
			graphics.fill(handle);
		graphics.setPaint(Color.BLACK);// 设置手柄边框颜色
		graphics.setStroke(new BasicStroke(1f));// 设置实线笔触
		// 绘制手柄边框
		for (Rectangle handle : handles)
			graphics.draw(handle);
	}

	// 返回当前有效的矩形
	public Rectangle getSelection() {
		return selection;
	}

	public static void main(String[] args) {
		new SelectableCanvas();
	}
}